#include <QCoreApplication>
#include <iostream>
using namespace std;

class  Base1
{
public:
     Base1() {}
    int m_A =1;
    virtual  void fun1(){

     }
};
class  Base2
{
public:
    Base2() {}
    int m_B =2;
    virtual void fun1(){

    }
};

class Son3: public Base1,public Base2{
public:
    int m_C= 3;
    void fun1() override{

    }


};
int main(int argc, char *argv[])
{
    Son3 s3;
    s3.fun1();
    // s3.Base1::fun1();
    // s3.Base2::fun1();

    Base2 s2 =  s3;
    Base1 s1 =  s3;


    return 0;
}




//  在实例化子类对象之前，必须先实例化父类对象
class  A99{
public :
    A99(){
        cout << "A99"<< endl;
    }
    int  a =99;
    void work(){
        cout << "Animal Work"<<endl;
    }
};
class B99:public A99{
public :
    B99(){
        cout << "B99"<< endl;
    }
    int a =88;
    void work(){
        cout << "B99 Work"<<endl;
    }
};

int main3(int argc, char *argv[])
{
    B99 b;
    b.A99::a = 999;

    cout <<  b.a<< endl;
    cout << b.A99::a <<endl; //
    b.work();
    b.A99::work();

    return 0;
}


int main2(int argc, char *argv[])
{

    B99 *b =new B99();
    A99 *a;
    a =b;

    return 0;
}



class Animal{
public:
    /**
     * @brief work
     * 可以被子类重新改写的方法
     */
public:
    virtual  void work(){
        cout << "Father work" <<endl;
    }
};

class Dog : public Animal{
public:
    /**
     * @brief work 方法覆盖：子类覆盖了父类的方法，但是父类方法是存在的；
     * 1、发生在子父类之间
     * 2、方法名相同
     * 3、参数也相同
     * 4、与方法的返回值类型无关
     */

    /**
     * 方法重写：重新改写
     * 1、发生在子父类之间
     * 2、方法名相同
     * 3、参数也相同
     * 4、返回值类型也必须相同；
     * 5、访问修饰符只能缩小，不能放大
     */
public:

    void   work(){
        cout << "dog  work" <<endl;
    }


};

class Cat  :public Animal{
public:
    void   work(){
        cout << "cat   work" <<endl;
    }
};

/**
 * @brief main
 * 子类对象可以隐士转换为父类对象
 * 但是父类对象必须通过强制类型转换才可以
 */
int main1(int argc, char *argv[])
{
    Cat  *c =new Cat();
    Animal *a ;
    a = c;
    c = (Cat *)a;
    // Dog *d =new Dog();
    // Animal * a;
    // a = d; // 里氏替换原则
    // a->work();

    // d =(Dog*) a ;





    // Dog *d =new Dog();
    // d->work();
    // Animal * a;
    // a = d ;
    // a->work();

    // Dog d;
    // Dog d ;
    // d.work();
    // cout << 2 <<    endl;
    // Animal a  = d ;
    // a.work();

}
